﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Un4seen.Bass;
//using Un4seen.Bass.AddOn.Enc;
using Un4seen.Bass.AddOn.Wma;
using System.IO;
using System.Runtime.InteropServices;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            fproc = proc;
        }


        public bool NoError(bool b, String fnc)
        {
            if (!b)
            {
              
                    BASSError err = Bass.BASS_ErrorGetCode();
                    MessageBox.Show(this, fnc + " error: " + err.ToString());
               
            }

            return b;
        }

        public bool NoError(int b, String fnc)
        {
            return NoError(b != 0, fnc);
       }

        bool firsthead = true;
        FileStream fs;
        String current_output;
        void proc(int handle, Un4seen.Bass.AddOn.Wma.BASSWMAEncodeCallback type, System.IntPtr buffer, int length, System.IntPtr user)
        {

            byte[] b = new byte[length];
            if (length > 0)
            Marshal.Copy(buffer, b, 0, length);
           

            switch (type)
            {
                case Un4seen.Bass.AddOn.Wma.BASSWMAEncodeCallback.BASS_WMA_ENCODE_HEAD:
                {
                    
                    if (firsthead)
                    {
                      fs = File.Create(current_output);
                    }
                    else
                    {
                        fs.Seek(0, SeekOrigin.Begin);
                    }

                    firsthead = false;
                    fs.Write(b, 0, length);

                } break;
                case Un4seen.Bass.AddOn.Wma.BASSWMAEncodeCallback.BASS_WMA_ENCODE_DATA:
                    {
                        fs.Write(b, 0, length);
                    } break;
                case Un4seen.Bass.AddOn.Wma.BASSWMAEncodeCallback.BASS_WMA_ENCODE_DONE:
                    {
                        fs.Close();
                        firsthead = true;
                    } break;
            }

           
        }

        WMENCODEPROC fproc; //have to be global variable

        public int ConvertFile(String fname, String fname2)
        {
            
            if (!File.Exists(fname))
            {
                MessageBox.Show(this, "File " + fname + " doesn't exists");
                return 0;
            }


            int hstream = 0;
            NoError( hstream = Bass.BASS_StreamCreateFile(fname, 0, 0, BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE), "BASS_StreamCreateFile");
         

            long length = Bass.BASS_ChannelGetLength(hstream, BASSMode.BASS_POS_BYTES);
            double time = Bass.BASS_ChannelBytes2Seconds(hstream, length);
            if (time > 39.0)
            {

                length = Bass.BASS_ChannelSeconds2Bytes(hstream, 39.0);
                NoError( Bass.BASS_StreamFree(hstream), "BASS_StreamFree");

          

                NoError(hstream = Bass.BASS_StreamCreateFile(fname, 0, length, BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE), "BASS_StreamCreateFile");
           
                time = Bass.BASS_ChannelBytes2Seconds(hstream, length);
            }


           
          
            int hwmeenc = BassWma.BASS_WMA_EncodeOpen(44100, 2, 0, 128000, fproc, System.IntPtr.Zero);
            //128kb/s
            NoError(hwmeenc, "BASS_WMA_EncodeOpen");
            if (hwmeenc == 0) MessageBox.Show(this, "There is no WMA codecs installed. Please run wmfdist.exe from program folder.");

            byte[] encBuffer = new byte[length];
            NoError(Bass.BASS_ChannelGetData(hstream, encBuffer, encBuffer.Length) > -1, "BASS_ChannelGetData");

            current_output = fname2;

            
            NoError(BassWma.BASS_WMA_EncodeSetTag(hwmeenc, "Title", Path.GetFileNameWithoutExtension(fname2)), "BASS_WMA_EncodeSetTag");
            NoError(BassWma.BASS_WMA_EncodeSetTag(hwmeenc, "WM/Genre", "Ringtone"), "BASS_WMA_EncodeSetTag");
            NoError(BassWma.BASS_WMA_EncodeWrite(hwmeenc, encBuffer, encBuffer.Length), "BASS_WMA_EncodeWrite");
            BassWma.BASS_WMA_EncodeClose(hwmeenc);

            NoError(Bass.BASS_StreamFree(hstream), "BASS_StreamFree");
           
            FileInfo f = new FileInfo(fname2);
            length =  f.Length;

            listBox1.Items.Add("File " + Path.GetFileName(fname) + " converted to " + Path.GetFileName(fname2) + " size: " + (length/1024).ToString() +"Kb");



            return 1;
           
        }


        private void Form1_Load(object sender, EventArgs e)
        {

            BassNet.Registration("trufanovan@gmail.com", "2X18371420152222"); //freeware registration

           // Version ver = Bass.BASS_GetVersion(4);

            NoError(Bass.BASS_Init(-1, 44000, 0, this.Handle), "BASS_Init");
   

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                textBox2.Text = folderBrowserDialog1.SelectedPath;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                foreach (String fname in openFileDialog1.FileNames)
                {
                    textBox1.Text += fname+";";
                }
                
                button3.Enabled = true;
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            MessageBox.Show(this, "not implemented!");
        }

        private void button3_Click(object sender, EventArgs e)
        {
            foreach (String fname in openFileDialog1.FileNames)
            {
                String out_fn = Path.Combine(textBox2.Text, Path.GetFileNameWithoutExtension(fname) + ".wma");
                ConvertFile(fname, out_fn);
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Bass.BASS_Free();
        }
    }
}
